home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
- * use is allowed under the terms of the DICE-LICENSE FILE,
- * DICE-LICENSE.TXT.
- */
- #include "vmake.h"
- #include "vmake_rev.h"
-
- Prototype int CreateWindow(void);
- Prototype void DestroyWindow(void);
- Prototype char *SkipAss(const char *);
-
- void myexit(void);
- int main(int, char **);
-
- struct GLOBAL global;
- __aligned struct FileInfoBlock vmfib;
-
- struct Library *GadToolsBase;
- struct Library *AslBase;
- struct Library *WorkbenchBase;
- struct Library *ArpBase;
-
- char *InitialFileName;
- char *ConfigName;
- short StartFromWB;
- short BuildIt;
- char *RexxScript;
- char Buf[256];
-
- #define TEMPLATE "PROJECT,REXX/K,CONFIG/K,BUILD/S"
-
- ULONG oldSeconds, oldMicros; /* for double click filtering */
-
- #define VM_PROJ 0
- #define VM_RSCRIPT VM_PROJ+1
- #define VM_CONFIG VM_RSCRIPT+1
- #define VM_BUILD VM_CONFIG+1
- #define OPT_COUNT VM_BUILD+1
-
- long vm_opts[OPT_COUNT];
-
- char *RexxHostName = "VMAKE" VERSTAG;
-
- /***********************************************************************************
- * Procedure: wbmain
- * Synopsis: rc = wbmain(WBStartup);
- * Purpose: Performs appropriate initialization to run program from Workbench
- * Notes: Parse tooltypes as a command. Note that we are CD'd into the
- * application's directory, not the tooltype's icon's dir.
- ***********************************************************************************/
- int wbmain(wbs)
- struct WBStartup *wbs;
- {
- struct DiskObject *dob;
- short i;
- short j;
- short FileSpecified = 0;
- short abortIt = 0;
-
- /*
- * Search for options, set current directory to last valid
- * disk object. Run commands specified by tool types in order
- */
-
- for (i = 0; i < wbs->sm_NumArgs; ++i)
- {
- BPTR saveLock = CurrentDir((BPTR)wbs->sm_ArgList[i].wa_Lock);
-
- if (i == wbs->sm_NumArgs - 1 && FileSpecified == 0)
- {
- InitialFileName = strdup(wbs->sm_ArgList[i].wa_Name);
- }
-
- if (dob = GetDiskObject(wbs->sm_ArgList[i].wa_Name))
- {
- if (dob->do_ToolTypes)
- {
- for (j = 0; dob->do_ToolTypes[j]; ++j)
- {
- char *ptr = dob->do_ToolTypes[j];
-
- if (strnicmp(ptr, "FILE=", 5) == 0)
- {
- InitialFileName = strdup(SkipAss(ptr));
- FileSpecified = 1;
- }
- else
- {
- if (strnicmp(ptr, "REXX=", 5) == 0)
- {
- RexxScript = strdup(SkipAss(ptr));
- }
- else
- {
- if (strnicmp(ptr, "CONFIG=", 7) == 0)
- ConfigName = strdup(SkipAss(ptr));
- else
- {
- if (strnicmp(ptr, "BUILD", 5) == 0)
- BuildIt = 1;
- else
- {
- /* These strings are needed for the requester */
- global.text[TEXT_OK] = "OK";
- global.text[TEXT_CANCEL] = "Cancel";
- /* OK to use any text slot - will get overlaid */
- global.text[1] = "Bad ToolType";
- /* Unfortunately the dos 1.3 version of request() */
- /* dies of a contagious plague... */
- if ((DOSBase->dl_lib.lib_Version >= 36) &&
- !request(0, 1, ptr, NULL))
- {
- abortIt = 1;
- break;
- }
- }
- }
- }
- }
- }
- }
- FreeDiskObject(dob);
- }
- CurrentDir(saveLock);
- if (abortIt)
- break;
- }
-
- if (abortIt == 0)
- {
- go_dir(wbs->sm_ArgList[wbs->sm_NumArgs-1].wa_Lock);
- setup_cli();
- StartFromWB = 1;
- main(1, NULL);
- }
- }
-
- /***********************************************************************************
- * Procedure: main
- * Synopsis: rc = main(argc, argv)
- * Purpose: The main entry point for the program
- ***********************************************************************************/
- int main(int argc, char **argv)
- {
- struct IntuiMessage *msg;
- struct RDargs *rdargs;
-
- if (!StartFromWB)
- {
- if (DOSBase->dl_lib.lib_Version >= 36)
- {
- rdargs = ReadArgs(TEMPLATE, vm_opts, NULL);
- if (rdargs == NULL)
- PrintFault(IoErr(), NULL);
- else
- {
- InitialFileName = (char *)vm_opts[VM_PROJ];
- RexxScript = (char *)vm_opts[VM_RSCRIPT];
- ConfigName = (char *)vm_opts[VM_CONFIG];
- BuildIt = vm_opts[VM_BUILD];
- }
- }
- else
- {
- if (argc != 1)
- {
- InitialFileName = argv[1];
- }
- }
- }
-
- /*
- * Open GadToolsBase/AslBase manually so we don't exit if they
- * don't exist.
- */
-
- GadToolsBase = OpenLibrary("gadtools.library", 0);
- AslBase = OpenLibrary("asl.library", 0);
- WorkbenchBase = OpenLibrary("workbench.library", 0);
-
- memset(&global, 0, sizeof(global));
-
- if (AslBase != NULL)
- /* Amigados version 2.0 or greater */
- {
- global.cbufsize = CBUF_SIZE_20; /* Long command lines */
- global.freq = AllocFileRequest();
- }
- else
- /* Amigados version 1.3 */
- {
- global.cbufsize = CBUF_SIZE_13; /* Short command lines */
- ArpBase = OpenLibrary("arp.library", 0);
- if (ArpBase != NULL)
- global.freq = ArpAllocFreq();
- }
-
- global.cbuf = malloc(global.cbufsize+1);
- global.rexxrs = malloc(global.cbufsize+1);
- if ((global.cbuf == NULL) || (global.rexxrs == NULL))
- return(20); /* not enough memory to run & no good way to say why not */
-
- if (ConfigName)
- {
- global.parsefail = parse_config(ConfigName);
- if (!global.parsefail)
- Sym_Set(SYM_CONFIG, ConfigName, NULL);
- }
- else
- {
- global.parsefail = parse_config(ALT_CONFIG_FILE);
- if (!global.parsefail)
- Sym_Set(SYM_CONFIG, ALT_CONFIG_FILE, NULL);
- else
- {
- if (global.parsefail == 2)
- {
- global.parsefail = parse_config(CONFIG_FILE);
- if (!global.parsefail)
- Sym_Set(SYM_CONFIG, CONFIG_FILE, NULL);
- }
- }
- }
-
- if (!global.parsefail)
- strcpy(global.title, global.text[TEXT_NOPROJ]);
- Sym_Set(SYM_ORIG_CFG, Sym_Lookup(SYM_CONFIG), 0);
-
- {
- /* We need to make the rexx port name available for them to use */
- char *pname;
- GetDiceRexxPortSlot(NULL, &pname);
- if (pname != NULL)
- Sym_Set(SYM_REXXPORT, pname, NULL);
- }
- /* REXX mode is initially non-interactive */
- global.rexxinter = 0;
- Sym_Set(SYM_REXXINTER, "OFF", NULL);
-
- while (!global.done)
- {
- /* global.screen is initialized to NULL to open on workbench screen */
- /* stay in screen/window loop till reset by JUMP */
- global.newscreen = 0;
-
- if(global.parsefail)
- {
- memset(global.menuitem, 0, sizeof(global.menuitem));
- global.gadlist = NULL; /* doesn't happen when we freegadlist() */
- }
-
- FillIn_RenderInfo(&global.ri, global.screen);
-
- /* Provide a default height/width so that we will get any errors displayed well */
- global.width = global.ri.ScreenWidth-50;
- global.height = global.ri.WindowTitle;
-
- global.ri.WindowTitle += MARGIN_TOP;
- global.ri.WindowLeft += MARGIN_LEFT;
- global.ri.WindowRight += MARGIN_RIGHT + RESIZE_WIDTH;
- global.ri.WindowBottom += MARGIN_BOTTOM;
-
- if (!global.parsefail)
- if (!init_gad_sizes(global.ri.ScreenWidth, global.ri.ScreenHeight,0))
- {
- init_gadgets();
- }
-
- if (!CreateWindow())
- {
- struct AppWindow *appwindow;
- struct MsgPort *appmsgport;
- struct AppMessage *appmsg;
- long waitflags = 1 << global.window->UserPort->mp_SigBit;
-
- if (WorkbenchBase && (WorkbenchBase->lib_Version >= 36))
- {
- if (appmsgport = CreateMsgPort())
- appwindow = AddAppWindowA(
- 1, /* userID */
- 0, /* ptr to userdata, prototyped as long */
- global.window, appmsgport, /*obvious*/
- NULL /* taglist */
- );
- if (appwindow) waitflags |= 1 << appmsgport->mp_SigBit;
- }
- else
- {
- appwindow = NULL;
- appmsgport = NULL;
- }
-
- waitflags |= 1 << RexxSigBit;
-
- set_gadgets(1);
-
- if (InitialFileName && !global.parsefail)
- {
- strcpy(global.filename, InitialFileName);
- do_command("READ");
- }
-
- /* ensure that console is available for REXX scripts etc. -- we're */
- /* either first time in or jumping to a new screen */
- TermSession();
- InitSession();
-
- if (RexxScript && !global.parsefail)
- {
- char buf[256];
- sprintf(buf, "ADDR REXX %s %%(_PORT_) %s",
- RexxScript, global.filename);
- do_command(buf);
- }
-
- /* If there's no project loaded now, we need to ghost most menu items */
- /* and cover the window so they can't play with the gadgets. */
- if ((global.filename[0] == 0) && !global.parsefail)
- {
- ghost_menus();
- cover_window();
- }
- else /* We have a project, do they want to build it right away? */
- if (BuildIt && !global.parsefail)
- do_command(global.text[CONFIG_BUILD]);
-
- /* only use these on the first pass */
- InitialFileName = RexxScript = NULL;
- BuildIt = 0;
-
- while(!global.done && !global.newscreen)
- {
- long mask;
-
- global.unghost = 0; /* will get set if we excute NEW or READ */
-
- mask = Wait(waitflags);
- while(msg = (struct IntuiMessage *)GetMsg(global.window->UserPort))
- {
- ULONG class;
- APTR iaddr;
- USHORT code;
- USHORT qual;
- ULONG Seconds, Micros;
- struct XItem *xitem;
-
- code = msg->Code;
- class = msg->Class;
- iaddr = msg->IAddress;
- qual = msg->Qualifier;
- Seconds = msg->Seconds;
- Micros = msg->Micros;
-
- ReplyMsg((struct Message *)msg);
-
- switch(class)
- {
- case CLOSEWINDOW:
- do_command("QUIT");
- break;
- case GADGETDOWN:
- /* We will only get this message from s list slider gadget */
- /* but should really verify ... oh well */
- global.mouseprop = 1; /* streamline prop gadget handling */
- ReportMouse(1, global.window);
- break;
- case GADGETUP:
- {
- int doubleclick;
-
- /* really want a reasonable way to initialize oldSecs/Micros for first call... */
- if (class == GADGETUP)
- {
- doubleclick = DoubleClick(oldSeconds, oldMicros,
- Seconds, Micros);
- oldSeconds = Seconds;
- oldMicros = Micros;
- }
- handle_hit((struct Gadget *)iaddr,
- (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) ? 1 : 0,
- doubleclick);
- /* restore this after mouse dragging stops to avoid an */
- /* extra screen flash. */
- global.mouseprop = 0; /* do gadget hits from now on */
- ReportMouse(0, global.window);
- break;
- }
- case NEWSIZE:
- set_gadgets(0);
- free_gadlist(global.gadlist);
- init_gad_sizes(global.window->Width,
- global.window->Height, 1);
- init_gadgets();
- SetBPen(global.rp, 0);
- SetAPen(global.rp, 0);
- /* debug - original
- RectFill( global.rp, global.ri.WindowLeft, global.ri.WindowTitle,
- global.window->Width - global.ri.WindowRight + MARGIN_RIGHT - 1,
- global.window->Height - global.ri.WindowBottom + MARGIN_BOTTOM - 1);
- */
- RectFill( global.rp, global.ri.WindowLeft - MARGIN_LEFT,
- global.ri.WindowTitle,
- global.window->Width - global.ri.WindowRight + MARGIN_RIGHT - 1,
- global.window->Height - global.ri.WindowBottom + MARGIN_BOTTOM - 1);
- set_gadgets(1);
- RefreshWindowFrame(global.window);
- break;
- case MENUPICK:
- while (code != MENUNULL)
- {
- xitem = (struct XItem *)
- ItemAddress(global.menu, code);
- do_command(xitem->userdata);
- code = xitem->item.NextSelect;
- }
- break;
- case VANILLAKEY:
- #ifdef DBG_JGM
- printf("Key:%d '%c'\n", code, code);
- switch (code)
- {
- case 'c':
- mark_clean();
- printf("set all objects clean\n");
- break;
- case 'd':
- {
- int dirty;
- dirty = test_dirty();
- printf("Dirty state is %d\n", dirty);
- break;
- }
- case 'g':
- ghost_menus();
- break;
- case 'u':
- unghost_menus();
- break;
- }
- #endif
-
- break;
- case MOUSEMOVE:
- if (global.mouseprop == 1)
- handle_list(global.filelist, global.filelist->slider,
- CLASS_PROP, NULL, 0);
- break;
- /*
- default:
- printf("Unknown IntuiMessage class %d\n", class);
- break;
- */
- }
- }
-
- if (appwindow && global.filelist)
- /* Must be Dos 2.0 or greater and must have list structure to put */
- /* file names into */
- {
- char appwinbuff[256];
-
- while (appmsg = (struct AppMessage *)GetMsg(appmsgport))
- {
- int i;
- char *exttext = global.text[CONFIG_EXT];
- int extlen = strlen(exttext);
- int argnmln;
- struct WBArg *argptr;
- BYTE *argname;
- char *projname; /* point to proj.DICE if found */
-
- argptr = appmsg->am_ArgList;
- for (i = 0; i < appmsg->am_NumArgs; i++)
- {
- int aproctype = 0;
- /* takes on values: 0 no defined processing */
- /* 1 add file name to list */
- /* 2 read in a project script */
- /* 3 go to dir - request script name */
- projname = NULL;
- argname = argptr->wa_Name;
- if (*argname) /* argument is a file, not a directory */
- {
- aproctype = 1; /* simple file */
- if ((argnmln = strlen(argname)) > extlen)
- if (!stricmp(argname + argnmln - extlen, exttext))
- {
- aproctype = 2; /* read project file */
- projname = (char *)argname;
- }
- }
- else /* directory - see if we can find a default project */
- {
- aproctype = 3; /* simple directory */
- }
-
- if (aproctype >= 2) /* see if it's OK to change directory */
- {
- if (save_current(1) == 0)
- {
- BPTR dlock;
- go_dir(argptr->wa_Lock);
- if ((dlock = DupLock(argptr->wa_Lock)) != NULL)
- {
- UnLock(global.homedir);
- global.homedir = dlock;
- }
- else
- aproctype = 0; /* READ wouldn't work... */
- }
- else
- /* give up on this one */
- aproctype = 0;
- }
-
- if (aproctype == 3) /* see if there is a default project */
- {
- if (Examine(argptr->wa_Lock, &vmfib))
- {
- BPTR dlock;
- strcpy(appwinbuff, vmfib.fib_FileName);
- strcat(appwinbuff, exttext);
- if (dlock = Lock(appwinbuff, SHARED_LOCK))
- {
- aproctype = 2; /* default project exists */
- projname = appwinbuff;
- UnLock(dlock);
- }
- }
- }
-
- /* now we've figure out how to process the object - do it */
- switch (aproctype)
- {
- case 1: /* simple filename to add to list */
- {
- int match = 0; /* directory match ? */
- int pdir = 0; /* prepend directory name? */
- int l;
- char *p;
- BPTR fplock = 0, wplock =0;
-
- if (SameLock(global.workdir, argptr->wa_Lock)
- == LOCK_SAME)
- match = 1;
- else
- {
- fplock = ParentDir(argptr->wa_Lock);
- if (SameLock(fplock, global.workdir)
- == LOCK_SAME)
- {
- match = 2;
- pdir = 1;
- }
- else
- {
- wplock = ParentDir(global.workdir);
- if (SameLock(wplock, argptr->wa_Lock)
- == LOCK_SAME)
- match = 3;
- else
- {
- if (SameLock(wplock, fplock)
- == LOCK_SAME)
- {
- match = 4;
- pdir = 1;
- }
- }
- }
- }
-
- *appwinbuff = '\0';
- if (match)
- /* Match Filename
- 0 <absolute path>/wa_Name
- 1 wa_Name
- 2 fparent/wa_Name
- 3 /wa_Name
- 4 /fparent/wa_Name
- */
- {
- if (match > 2) /* 3 or 4 */
- strcpy(appwinbuff, "/");
- if (pdir) /* parent dir name required */
- {
- if (Examine(argptr->wa_Lock, &vmfib))
- {
- strcat(appwinbuff, vmfib.fib_FileName);
- /* note: fplock is valid when pdir = 1 */
- if (fplock == 0) /* name is root */
- strcat(appwinbuff, ":");
- }
- else
- match = 0; /* no path name - forget it */
- }
- }
- else
- if (NameFromLock(argptr->wa_Lock, appwinbuff, 255))
- pdir = 1; /* have path in appwinbuff now */
-
- /* path (if any) in appwinbuff, name in wa_Name */
- l = strlen(appwinbuff);
- p = appwinbuff+l;
-
- if (pdir) /* parent dir name in appwinbuff */
- /* append "/" if approriate */
- if (*(p-1) != ':')
- {
- strcpy(p, "/");
- p++;
- }
- if (strlen(argptr->wa_Name) < (255-l))
- strcpy(p, argptr->wa_Name);
- handle_list(global.filelist, NULL, CLASS_ADD, appwinbuff, 0);
-
- if (fplock)
- UnLock(fplock);
- if (wplock)
- UnLock(wplock);
- break;
-
- }
- case 2: /* project script: proj.DICE */
- {
- char cmdbuff[266];
-
- strcpy(cmdbuff, "READ ");
- strcat(cmdbuff, projname);
- do_command(cmdbuff);
- break;
- }
- case 3: /* go to directory and prompt for file */
- {
- char cmdbuff[] = "READ ?";
- do_command(cmdbuff);
- break;
- }
- }
- argptr++;
- }
- ReplyMsg((struct Message *)appmsg);
- }
- }
-
- /* See if they want us to do any rexx commands */
- if (mask & (1 << RexxSigBit))
- ProcessRexxCommands(NULL);
-
- /* we had to defer this because it messes up no end if you try to */
- /* change the menus while processing a menupick intuimessage */
- if (global.unghost) /* set by Read or New commands */
- {
- if (global.filename[0]) /* Read or New might have failed... */
- { /* but they didn't */
- unghost_menus();
- uncover_window();
- }
- else
- { /* or else they did */
- ghost_menus();
- cover_window();
- }
- }
- }
- if (appwindow) RemoveAppWindow(appwindow);
- if (appmsgport) DeleteMsgPort(appmsgport);
- set_gadgets(0);
- free_gadlist(global.gadlist);
- DestroyWindow();
- }
-
- CleanUp_RenderInfo(&global.ri);
- /* this is where the open/close window loop ends */
-
- }
- UnLock(global.workdir);
- UnLock(global.homedir);
-
- if (global.freq && (AslBase != NULL)) FreeFileRequest(global.freq);
-
- if (GadToolsBase != NULL) CloseLibrary(GadToolsBase);
- if (AslBase != NULL) CloseLibrary(AslBase);
- if (ArpBase != NULL) CloseLibrary(ArpBase);
- if (WorkbenchBase != NULL) CloseLibrary(WorkbenchBase);
- return(0);
- }
-
- /***********************************************************************************
- * Procedure: CreateWindow
- * Synopsis: rc = CreateWindow();
- * Purpose: Create the window on the current screen using the current environment
- ***********************************************************************************/
- int CreateWindow()
- {
- struct NewWindow nw;
-
- struct TagItem wintags[] = {
- { WA_PubScreen, (ULONG)global.screen },
- /* The screen we want to be on */
- { WA_PubScreenFallBack, (ULONG)TRUE }, /* Or workbench if not */
- { TAG_DONE, (ULONG)0 }
- };
-
-
- memset(&nw, 0, sizeof(nw));
-
- nw.Width = global.width;
- nw.Height = global.height;
- nw.LeftEdge = (global.ri.ScreenWidth - nw.Width ) / 2;
- nw.TopEdge = (global.ri.ScreenHeight - nw.Height) / 2;
- nw.MinWidth = 4*BUTTON_WIDTH;
- nw.MinHeight = 110;
- nw.MaxWidth = 0xffff;
- nw.MaxHeight = 0xffff;
-
- if ((nw.Width < 0) || (nw.Height < 0))
- return(1);
- nw.DetailPen = nw.BlockPen = -1;
- if (global.parsefail)
- {
- nw.IDCMPFlags = CLOSEWINDOW;
- nw.Flags = WINDOWDEPTH |
- WINDOWCLOSE |
- WINDOWDRAG |
- SIMPLE_REFRESH |
- ACTIVATE |
- NOCAREREFRESH;
-
- }
- else
- {
- nw.IDCMPFlags = GADGETUP |
- GADGETDOWN |
- MENUPICK |
- MOUSEMOVE |
- VANILLAKEY |
- NEWSIZE |
- CLOSEWINDOW;
- nw.Flags = WINDOWDEPTH |
- WINDOWSIZING |
- WINDOWCLOSE |
- WINDOWDRAG |
- SIMPLE_REFRESH |
- ACTIVATE |
- NOCAREREFRESH;
-
- }
- nw.Title = global.title;
- if (AslBase != 0) /* public screens come with Dos 2.0... */
- {
- nw.Type = PUBLICSCREEN;
-
- global.window = OpenWindowTagList(&nw, wintags);
- if (global.screen)
- UnlockPubScreen(NULL, global.screen);
- }
- else /* do the Dos 1.3 version */
- {
- nw.Type = WBENCHSCREEN;
- global.window = OpenWindow(&nw);
- }
-
- if (global.window == NULL) return(2);
- SetWindowTitles(global.window, global.title, global.title2);
- global.rp = global.window->RPort;
- enable_menu();
- return(0);
- }
-
- /***********************************************************************************
- * Procedure: DestroyWindow
- * Synopsis: (void)DestroyWindow();
- * Purpose: Make the current window go away
- ***********************************************************************************/
- void DestroyWindow()
- {
- free_menus(global.menu);
- CloseWindow(global.window);
- global.window = 0; /* do we need this? */
- }
-
-
- /***********************************************************************************
- * Procedure: SkipAss
- * Synopsis: p = SkipAss(ptr)
- * Purpose: Skip whitespace in tooltype assignment
- ***********************************************************************************/
- char * SkipAss(const char *ptr)
- {
- while (*ptr && *ptr != '=')
- ptr++;
- if (*ptr == '=')
- {
- for (ptr++; *ptr == ' ' || *ptr == '\t'; ptr++)
- ;
- }
- return(ptr);
- }
-
- /***********************************************************************************
- * Procedure: DoRexxCommand
- * Synopsis: rc = DoRexxCommand(msg, port, arg, pres)
- * Purpose: Handling executing a rexx command
- ***********************************************************************************/
- long DoRexxCommand(void *msg, /* RexxMsg structure if we need it */
- struct MsgPort *port, /* MsgPort structure if we need it */
- char *arg0, /* arg0 */
- char **pres /* where to put our result if rc==0 */
- )
- {
- if (!global.rexxinter)
- global.inrexx = 1; /* controls some error processing */
- global.rexxmsgs = 1; /* always get messages & return codes */
- global.rexxrs[0] = '\0'; /* clear any leftover value */
- global.rexxrc = 0; /* presumed innocent until proven guilty */
- InitSession(); /* ensure console window will be around */
-
- strcpy(global.rexxrs, "Command OK");
- do_command(arg0);
-
- global.rexxmsgs = 0;
- global.inrexx = 0; /* revert to non-rexx error handling */
- if (global.rexxrc == 0)
- *pres = global.rexxrs; /* result string (might point to "") */
- else
- global.rexxrc += 1; /* to match numbering in documentation */
- return(global.rexxrc);
- }
-
-